home *** CD-ROM | disk | FTP | other *** search
- /*
- * fitspline.c
- *
- * Practical Algorithms for Image Analysis
- *
- * Copyright (c) 1997, 1998, 1999 MLMSoftwareGroup, LLC
- */
-
- /* FITSPLINE: program performs spline fit upon image lines, where
- * input is in PCC code, and where spline nodes have been
- * determined by polygonalization
- * usage: fitspline infile outimg [-t THRESHOLD] [-g GRANULARITY] [-i] [-L]
- */
-
- #define THRESH_DFLT 5
- #define GRAN_DFLT 5 /* granularity of pts between spline nodes */
-
- #include <stdio.h>
- #include <string.h>
- #include <stdlib.h>
- #include <images.h>
- #include <tiffimage.h>
- #include "pcc2.h" /* for PCC programs */
- extern void print_sos_lic ();
-
- unsigned char *fcCode; /* code storage */
- long nByteCode; /* no. bytes in code storage */
-
- long xytoline (struct point *, long *, long *, long *);
- long spline (struct point *, long, unsigned char **,
- struct point, long, short);
- long usage (short);
- long input (int, char **, long *, long *, short *);
-
-
- main (argc, argv)
- int argc;
- char *argv[];
- {
- Image *imgO; /* pointer to output image structure */
- unsigned char **image; /* output image array */
- long width, height; /* image size */
- struct point imgSize; /* image size */
- long thresh; /* threshold for fit */
- short splineType; /* =1 for approx spline; or =2 for interp */
- long gran; /* granularity of pts between spline nodes */
- struct point *data; /* data curve */
- long nData; /* no. coords in data curve */
- long nSegments; /* number of segments found */
- long nStructs; /* number of line structures found */
- long lengthSqr, area; /* length sqr.ed and area of line fits */
- long deltaX, deltaY; /* x and y increments for line fits */
- long iNode, nNodes; /* index and number of spline node points */
- struct point *nodes; /* array of spline nodes for each structure */
- struct point pt0; /* points to connect fits between */
- long x, y;
- long i;
-
- /* user input */
- if (input (argc, argv, &thresh, &gran, &splineType) < 0)
- return (-1);
-
- /* open input PCC file */
- if (pccread (argv[1], &fcCode, &nByteCode, &width, &height) == -1)
- exit (1);
- printf ("image size: %dx%d, PCC length = %d\n", width, height, nByteCode);
- imgSize.x = width;
- imgSize.y = height;
-
- /* allocate space for data coordinate array */
- if ((data = (struct point *)
- calloc (nByteCode * MAXPERCODE, sizeof (long))) == NULL) {
- printf ("FITSPLINE: not enough memory -- sorry");
- return (-1);
- }
-
- /* construct tables of feature chain decodes */
- pccdecodes ();
-
- /* perform feature chain decoding */
- pcc2xy (data, &nData);
-
- /* re-allocate data memory */
- data[nData++].x = -STOPCODE;
- if ((data = (struct point *)
- realloc (data, nData * sizeof (struct point))) == NULL) {
- printf ("FITSPLINE: not enough memory -- sorry");
- return (-2);
- }
-
- /* find x,y coordinates for each line */
- if (xytoline (data, &nData, &nSegments, &nStructs) < 0)
- return (-1);
-
- /* allocate output image */
- imgO = ImageAlloc (height, width, 8);
- image = ImageGetPtr (imgO);
-
- /* initialize image */
- for (y = 0; y < height; y++)
- for (x = 0; x < width; x++)
- image[y][x] = 255;
-
- /* allocate spline node memory */
- if ((nodes = (struct point *)
- calloc (nData, sizeof (struct point))) == NULL) {
- printf ("FITSPLINE: not enough memory -- sorry");
- return (-3);
- }
-
- /* determine polygonal fits */
- for (i = 0, iNode = nNodes = 0; i < nData; i++) {
- if (data[i].x != -1) {
- nodes[iNode].x = data[i].x;
- nodes[iNode++].y = data[i].y;
- nodes[iNode].x = data[i].x; /* replicate first point */
- nodes[iNode++].y = data[i].y;
- nNodes++;
- pt0.x = data[i].x;
- pt0.y = data[i].y;
- i++;
- if (data[i].x < 0) { /* one pixel line */
- image[nodes[iNode - 1].y][nodes[iNode - 1].x] = 255;
- iNode = 0;
- nNodes++;
- }
- else {
- lengthSqr = area = 0;
- while (data[i].x >= 0) {
- x = data[i].x - pt0.x;
- y = data[i].y - pt0.y;
- deltaX = data[i].x - data[i - 1].x;
- deltaY = data[i].y - data[i - 1].y;
- lengthSqr += 2 * (x * deltaX + y * deltaY)
- + deltaX * deltaX + deltaY * deltaY;
- area += x * deltaY - y * deltaX;
- if ((area * area) > (thresh * lengthSqr)) {
- nodes[iNode].x = data[i].x;
- nodes[iNode++].y = data[i].y;
- nNodes++;
- pt0.x = data[i].x;
- pt0.y = data[i].y;
- lengthSqr = area = 0;
- }
- i++;
- }
- if (lengthSqr > 0) {
- nodes[iNode].x = data[i - 1].x;
- nodes[iNode++].y = data[i - 1].y;
- nNodes++;
- }
- nodes[iNode].x = data[i - 1].x; /* replicate final point */
- nodes[iNode++].y = data[i - 1].y;
- spline (nodes, iNode, image, imgSize, gran, splineType);
- iNode = 0;
- }
- --i;
- }
- }
-
- printf ("Number of spline nodes = %d.\n", nNodes);
-
-
- /* write image output file */
- ImageOut (argv[2], imgO);
-
- return (0);
- }
-
-
-
- /* USAGE: function gives instructions on usage of program
- * usage: usage (flag)
- * When flag is 1, the long message is given, 0 gives short.
- */
-
- long
- usage (flag)
- short flag; /* flag =1 for long message; =0 for short message */
- {
-
- /* print short usage message or long */
- printf ("USAGE: fitspline infile outimg [-t THRESHOLD] [-g GRANULARITY] [-i] [-L] ");
- if (flag == 0)
- return (-1);
-
- printf ("\nfitspline performs spline fitting to image\n");
- printf ("lines to produce smooth curve approximations.\n\n");
- printf ("ARGUMENTS:\n");
- printf (" infile: input filename (PCC)\n");
- printf (" outimg: output image filename (TIF)\n\n");
- printf ("OPTIONS:\n");
- printf (" -t THRESH: threshold on error for spline node determination;\n");
- printf (" nodes are found from polygonalization. (Dflt = %d).\n", THRESH_DFLT);
- printf (" The smaller this threshold, the closer the\n");
- printf (" approximation of the original data, but more spline\n");
- printf (" line fits will be required.\n");
- printf (" -g GRANULARITY: number of points between each spline node;\n");
- printf (" the greater the number of points, the smoother the\n");
- printf (" approximation. (default = %d)\n", GRAN_DFLT);
- printf (" -i: to perform interpolation fitting, that is\n");
- printf (" the fit runs through node points; a B-spline is used.\n");
- printf (" The default is NOT interpolation, instead it is an\n");
- printf (" approximation spline; a cardinal spline is used.\n");
- printf (" The approximation spline is yields a close fit, but one\n");
- printf (" one that does not usually pass through the node points.\n");
- printf (" The approximation spline appears smoother than the\n");
- printf (" interpolation spline.\n");
- printf (" -L: print Software License for this module\n");
-
-
- return (-1);
- }
-
-
- /* INPUT: function reads input parameters
- * usage: input (argc, argv, &thresh, &gran, &splineType)
- */
-
- #define USAGE_EXIT(VALUE) {usage (VALUE); return (-1);}
-
- long
- input (argc, argv, thresh, gran, splineType)
- int argc;
- char *argv[];
- long *thresh; /* threshold on polygonal fit */
- long *gran; /* granularity of spline pts between nodes */
- short *splineType; /* =1 for approximation spline; or =2 for
- * * interpolation spline */
- {
- long n;
-
- if (argc == 1)
- USAGE_EXIT (1);
- if (argc == 2)
- USAGE_EXIT (0);
-
- *thresh = THRESH_DFLT;
- *gran = GRAN_DFLT;
- *splineType = 1;
-
- for (n = 3; n < argc; n++) {
- if (strcmp (argv[n], "-t") == 0) {
- if (++n == argc)
- USAGE_EXIT (0);
- *thresh = (long) atol (argv[n]);
- }
- else if (strcmp (argv[n], "-g") == 0) {
- if (++n == argc)
- USAGE_EXIT (0);
- *gran = (long) atol (argv[n]);
- }
- else if (strcmp (argv[n], "-i") == 0)
- *splineType = 2;
- else if (strcmp (argv[n], "-L") == 0) {
- print_sos_lic ();
- exit (0);
- }
- else
- USAGE_EXIT (0);
- }
-
-
- return (0);
- }
-